package com.bootx.predict;

import com.bootx.predict.pojo.PredictPlugin;
import com.bootx.predict.pojo.PredictionResult;
import com.bootx.predict.pojo.RedPacketBatch;
import com.bootx.predict.pojo.RedPacketRecord;
import com.bootx.predict.util.PredictUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author black
 * 滑动窗口策略 (Sliding Window Strategy)
 */
@Component("slidingWindowPredict")
public class SlidingWindowPredict extends PredictPlugin {
    private final int windowSize = 5;
    @Override
    public String getName() {
        return "slidingWindowPredict";
    }

    @Override
    public List<PredictionResult> predict(List<RedPacketBatch> list, Set<Integer> indexes) {
        List<RedPacketRecord> history = PredictUtils.parseData(list);
        // 找出最近 windowSize 轮的 batchId
        List<Long> sortedBatchIds = list.stream()
                .map(RedPacketBatch::getBatchId)
                .sorted(Comparator.reverseOrder())
                .limit(windowSize)
                .toList();

        // 过滤最近 N 轮的记录
        Set<Long> recentBatchIds = new HashSet<>(sortedBatchIds);
        List<RedPacketRecord> recentRecords = history.stream()
                .filter(r -> recentBatchIds.contains((long) r.getRoundId()))
                .toList();
        // 统计
        Map<Integer, List<RedPacketRecord>> grouped = recentRecords.stream()
                .collect(Collectors.groupingBy(RedPacketRecord::getIndex));
        List<PredictionResult> results = new ArrayList<>();
        for (int idx : indexes) {
            List<RedPacketRecord> records = grouped.getOrDefault(idx, Collections.emptyList());
            int total = records.size();
            int oddCount = (int) records.stream().filter(r -> PredictUtils.isAmountOdd(r.getAmount())).count();
            double probability = total > 0 ? (double) oddCount / total : 0.5;
            double avgOpenTime = records.stream().mapToInt(RedPacketRecord::getOpenTime).average().orElse(0);
            results.add(new PredictionResult(idx, total, oddCount, probability, Double.valueOf(avgOpenTime+"").intValue()));
        }

        return results;
    }

}
